using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.Profile;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using Commerce.Common;
using Commerce.Providers;
using CommerceForUmbraco.profile;

namespace CommerceForUmbraco.usercontrols
{
    public partial class MultiPageCheckout2 : System.Web.UI.UserControl
    {
        // the current order - for shipping and tax calcs
        protected Order currentOrder = null;
        // the Umbraco Member Profile
        protected CommerceForUmbraco.profile.UmbracoProfile umbProfile;

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                // get the order and set the order display
                SetCurrentOrder();
                SetProfile(currentOrder.UserName);
                SetOrderInfo();

                lblOrderItems.Text = currentOrder.mcOrderItemsTable();

            }
            catch (Exception ex)
            {
                message.Text = "We're sorry, an error occured.<br />" + ex.Message;
            }

        }

        #region button handlers

        /// <summary>
        /// Handles the Click event of the shippingContinue control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void shippingContinue_Click(object sender, EventArgs e)
        {
            try
            {
                // set billing address if we have it, otherwise set to the shipping address
                if (this.BillAddressEntry.SelectedAddress.City.Length == 0)
                {
                    this.BillAddressEntry.SelectedAddress = this.ShipAddressEntry.SelectedAddress;
                }

                // set the address for the order
                currentOrder.BillingAddress = BillAddressEntry.SelectedAddress;
                currentOrder.ShippingAddress = ShipAddressEntry.SelectedAddress;

                    // see if we have all required fields
                    Page.Validate();

                    if (Page.IsValid)
                    {
                        // set tax for the currentOrder
                        currentOrder.TaxAmount = GetCurrentOrderTax(currentOrder.BillingAddress.StateOrRegion);
                        umbProfile.CurrentOrderTax = currentOrder.TaxAmount.ToString();

                        // save the address data to the UserProfie
                        SaveUmbracoAddresses();

                        lblOrderItems.Text = currentOrder.mcOrderItemsTable();
                        
                        // transfer to part 3 - shipping and billing
                        Response.Redirect("checkout3.aspx", true);
                    }
            }
            catch
            {
                // catch all exceptions and put up error display
                message.Text = "There is a problem with the address entered.  Please check your input, Thanks!";
            }
        }

        /// <summary>
        /// Handles the Click event of the backButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void backButton_Click(object sender, EventArgs e)
        {
            try
            {
                // set billing address if we have it, otherwise set to the shipping address
                if (this.BillAddressEntry.SelectedAddress.City.Length == 0)
                {
                    this.BillAddressEntry.SelectedAddress = this.ShipAddressEntry.SelectedAddress;
                }

                // set the address for the order
                currentOrder.BillingAddress = BillAddressEntry.SelectedAddress;
                currentOrder.ShippingAddress = ShipAddressEntry.SelectedAddress;

                // see if we have all required fields
                Page.Validate();

                if (Page.IsValid)
                {
                    // save the address data to the UserProfie
                    SaveUmbracoAddresses();

                    // set tax for the currentOrder
                    currentOrder.TaxAmount = GetCurrentOrderTax(umbProfile.BillingStateOrRegion);
                    umbProfile.CurrentOrderTax = currentOrder.TaxAmount.ToString();

                    lblOrderItems.Text = currentOrder.mcOrderItemsTable();

                    // transfer to part 1 - email address
                    Response.Redirect("checkout.aspx", true);
                }
            }
            catch (Exception)
            {
                // catch all exceptions and put up error display
                message.Text = "There is a problem with the address entered.  Please check your input, Thanks!";
            }
        }

        #endregion

        #region checkout utility methods

        /// <summary>
        /// Sets the order info for address, shipping, and tax
        /// </summary>
        void SetOrderInfo()
        {
            currentOrder.ShippingAddress = umbProfile.GetCommerceShippingAddress();
            currentOrder.BillingAddress = umbProfile.GetCommerceBillingAddress();

            // save the addresses as HTML strings for ERP integration
            currentOrder.ShipToAddress = currentOrder.ShippingAddress.ToHtmlString();
            currentOrder.BillToAddress = currentOrder.BillingAddress.ToHtmlString();

            // get tax
            if (currentOrder.ShippingAddress.StateOrRegion.Length > 0)
                currentOrder.TaxAmount = GetCurrentOrderTax(umbProfile.BillingStateOrRegion);

            if (currentOrder.BillingAddress != null)
            {
                currentOrder.FirstName = currentOrder.BillingAddress.FirstName;
                currentOrder.LastName = currentOrder.BillingAddress.LastName;
                currentOrder.Email = currentOrder.BillingAddress.Email;
            }

            // update the display if profile addresses are present

            // shipping address
            if (currentOrder.ShippingAddress.City.Length != 0)
            {
                ShipAddressEntry.SelectedAddress = currentOrder.ShippingAddress;
            }

            // billing address
            if (currentOrder.BillingAddress.City.Length != 0)
            {
                BillAddressEntry.SelectedAddress = currentOrder.BillingAddress;
            }
            else if (currentOrder.ShippingAddress.City.Length != 0)
            {
                BillAddressEntry.SelectedAddress = currentOrder.ShippingAddress;
            }

            // set email address as provided in Step 1
            if (currentOrder.UserName != null)
            {
                BillAddressEntry.SelectedAddress.Email = currentOrder.UserName;
                ShipAddressEntry.SelectedAddress.Email = currentOrder.UserName;
            }

        }

        /// <summary>
        /// Sets the current order based on the "shopperID" cookie value
        /// </summary>
        public void SetCurrentOrder()
        {
            if (currentOrder == null)
                currentOrder = OrderController.GetCurrentOrder();
        }

        /// <summary>
        /// Sets the profile to the current user and initializes ProfileBase
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        public void SetProfile(string userName)
        {
            // set the Umbraco profile
            umbProfile = new CommerceForUmbraco.profile.UmbracoProfile(userName);
        }

        /// <summary>
        /// Saves the order address to the integration address table
        /// </summary>
        protected void SaveIntegrationAdress()
        {
            IntegrationAddress shipping = null;
            IntegrationAddress billing = null;

            // check to see if we have records for this order already
            // SHIPPING
            int shipExistsCount = new SubSonic.Query(IntegrationAddress.Schema)
                .AddWhere(IntegrationAddress.Columns.AddressType, "SHIP")
                .AddWhere(IntegrationAddress.Columns.OrderId, currentOrder.OrderID.ToString()).GetCount("orderId");

            if (shipExistsCount > 0)
            {
                // update shipAddress
                string addressId = new SubSonic.Select(IntegrationAddress.Columns.AddressId)
                    .From(IntegrationAddress.Schema)
                    .WhereExpression(IntegrationAddress.Columns.AddressType).IsEqualTo("SHIP")
                    .And(IntegrationAddress.Columns.OrderId).IsEqualTo(currentOrder.OrderID.ToString())
                    .ExecuteScalar<string>();

                shipping = new IntegrationAddress(addressId);
            }
            else
            {
                shipping = new IntegrationAddress();
            }
            // BILLING
            int billExistsCount = new SubSonic.Query(IntegrationAddress.Schema)
                .AddWhere(IntegrationAddress.Columns.AddressType, "BILL")
                .AddWhere(IntegrationAddress.Columns.OrderId, currentOrder.OrderID.ToString()).GetCount("orderId");

            if (billExistsCount > 0)
            {
                // update shipAddress
                string addressId = new SubSonic.Select(IntegrationAddress.Columns.AddressId)
                    .From(IntegrationAddress.Schema)
                    .WhereExpression(IntegrationAddress.Columns.AddressType).IsEqualTo("BILL")
                    .And(IntegrationAddress.Columns.OrderId).IsEqualTo(currentOrder.OrderID.ToString())
                    .ExecuteScalar<string>();

                billing = new IntegrationAddress(addressId);
            }
            else
            {
                billing = new IntegrationAddress();
            }

            try
            {

                shipping.AddressType = "SHIP";
                shipping.OrderId = currentOrder.OrderID;
                shipping.FirstName = this.ShipAddressEntry.SelectedAddress.FirstName;
                shipping.LastName = this.ShipAddressEntry.SelectedAddress.LastName;
                shipping.Email = this.ShipAddressEntry.SelectedAddress.Email;
                shipping.Address1 = TrimData(this.ShipAddressEntry.SelectedAddress.Address1, 40);
                shipping.Address2 = TrimData(this.ShipAddressEntry.SelectedAddress.Address2, 40);
                shipping.City = TrimData(this.ShipAddressEntry.SelectedAddress.City, 25);
                shipping.Country = TrimData(this.ShipAddressEntry.SelectedAddress.Country, 3);
                shipping.State = TrimData(this.ShipAddressEntry.SelectedAddress.StateOrRegion, 3);
                shipping.Zip = TrimData(this.ShipAddressEntry.SelectedAddress.Zip, 12);
                shipping.Phone = "0"; // TrimData(shipAddressEntry.SelectedAddress.Phone, 25);

                shipping.Save("checkout");

                billing.AddressType = "BILL";
                billing.OrderId = currentOrder.OrderID;
                billing.FirstName = this.BillAddressEntry.SelectedAddress.FirstName;
                billing.LastName = this.BillAddressEntry.SelectedAddress.LastName;
                billing.Email = this.BillAddressEntry.SelectedAddress.Email;
                billing.Address1 = TrimData(this.BillAddressEntry.SelectedAddress.Address1, 40);
                billing.Address2 = TrimData(this.BillAddressEntry.SelectedAddress.Address2, 40);
                billing.City = TrimData(this.BillAddressEntry.SelectedAddress.City, 25);
                billing.Country = TrimData(this.BillAddressEntry.SelectedAddress.Country, 3);
                billing.State = TrimData(this.BillAddressEntry.SelectedAddress.StateOrRegion, 3);
                billing.Zip = TrimData(this.BillAddressEntry.SelectedAddress.Zip, 12);
                billing.Phone = "0";  // TrimData(billAddressEntry.SelectedAddress.Phone, 25);

                billing.Save("checkout");

            }
            catch (Exception ex)
            {
                // swallow the error for now - we've already processed the order
                message.Text = "Your order was successfully placed but we're sorry, an error occured.<br />" + ex.Message;
            }

        }

        protected string TrimData(string data, int length)
        {
            int totalLength = data.Length;

            if (totalLength > length)
            {
                return data.Substring(0, length);
            }
            else
            {
                return data;
            }
        }

        void SaveUmbracoAddresses()
        {
            // saves the entered address to the user profile
            SetProfile(currentOrder.UserName);

            // Shipping Address
            umbProfile.ShippingFirstName = this.ShipAddressEntry.SelectedAddress.FirstName;
            umbProfile.ShippingLastName = this.ShipAddressEntry.SelectedAddress.LastName;
            umbProfile.ShippingEmail = this.ShipAddressEntry.SelectedAddress.Email;
            umbProfile.ShippingAddress1 = this.ShipAddressEntry.SelectedAddress.Address1;
            umbProfile.ShippingAddress2 = this.ShipAddressEntry.SelectedAddress.Address2;
            umbProfile.ShippingCity = this.ShipAddressEntry.SelectedAddress.City;
            umbProfile.ShippingCountry = this.ShipAddressEntry.SelectedAddress.Country;
            umbProfile.ShippingStateOrRegion = this.ShipAddressEntry.SelectedAddress.StateOrRegion;
            umbProfile.ShippingZip = this.ShipAddressEntry.SelectedAddress.Zip;
            umbProfile.ShippingPhone = this.ShipAddressEntry.SelectedAddress.Phone;

            // Billing Address
            umbProfile.BillingFirstName = this.BillAddressEntry.SelectedAddress.FirstName;
            umbProfile.BillingLastName = this.BillAddressEntry.SelectedAddress.LastName;
            umbProfile.BillingEmail = this.BillAddressEntry.SelectedAddress.Email;
            umbProfile.BillingAddress1 = this.BillAddressEntry.SelectedAddress.Address1;
            umbProfile.BillingAddress2 = this.BillAddressEntry.SelectedAddress.Address2;
            umbProfile.BillingCity = this.BillAddressEntry.SelectedAddress.City;
            umbProfile.BillingCountry = this.BillAddressEntry.SelectedAddress.Country;
            umbProfile.BillingStateOrRegion = this.BillAddressEntry.SelectedAddress.StateOrRegion;
            umbProfile.BillingZip = this.BillAddressEntry.SelectedAddress.Zip;
            umbProfile.BillingPhone = this.BillAddressEntry.SelectedAddress.Phone;

            // Commerce Specifics
            umbProfile.PayPalPayerID = Request.QueryString.Get("PayerID");
            umbProfile.PayPalToken = Request.QueryString.Get("token");
            umbProfile.CurrentOrderTax = currentOrder.TaxAmount.ToString();

            // Opt-in selection
            if (optInCheckBox.Checked)
            {
                umbProfile.OptIn = true;
            }
            else
            {
                umbProfile.OptIn = false;
            }
        }

        /// <summary>
        /// Gets the current order tax based on supplied State Code
        /// </summary>
        /// <returns>Tax Amount</returns>
        protected decimal GetCurrentOrderTax(string StateCode)
        {
            decimal dTax = 0;

            try
            {
                USState state = (USState)Utility.StringToEnum(typeof(Commerce.Common.USState), StateCode);

                dTax = OrderController.CalculateTax(state, currentOrder.CalculateSubTotal(), currentOrder.ShippingAmount);

                return dTax;
            }
            catch
            {
                return 0;
            }
        }

    #endregion

    }
}